home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / SOURCE.BIN / HorizontalSlider.java < prev    next >
Encoding:
Java Source  |  1997-06-19  |  12.5 KB  |  487 lines

  1. package symantec.itools.awt;
  2.  
  3.  
  4. import java.awt.Graphics;
  5. import java.awt.Color;
  6. import java.awt.Event;
  7.  
  8.  
  9. /**
  10.  * A HorizontalSlider component. This component is used to select one value
  11.  * from a continuous range of values. It has a movable thumb in front of a 
  12.  * gauge with ticks marks on it.
  13.  * <p>
  14.  * @see symantec.itools.awt.Slider
  15.  * @see symantec.itools.awt.VerticalSlider
  16.  * @version 1.0, Nov 26, 1996
  17.  * @author Symantec
  18.  */
  19.  
  20. //     02/15/97    RKM    Added validate - Fixes problem where calls to setMinValue & setMaxValue
  21. //                    would not work if called after reshape
  22. //     02/27/97    RKM    Merged in Scott's change to use the background color of the component
  23.  
  24. public class HorizontalSlider
  25.     extends Slider
  26. {
  27.     /**
  28.      * Length of the gauge ticks in pixels.
  29.      */
  30.     protected static final int TICK_HEIGHT  = 4;
  31.     private static final int BORDER_X       = 15;
  32.     private static final int BORDER_Y       = 10;
  33.  
  34.     private HorizontalSliderTick tick[];
  35.     private HorizontalSliderThumb thumb;
  36.  
  37.     /**
  38.      * Constructs a default HorizontalSlider. The ticks
  39.      * are drawn on both sides of the gauge with a frequency of 1. 
  40.      * The minimum value is 1. The maximum value is 10. The
  41.      * border is shown.
  42.      */
  43.     public HorizontalSlider()
  44.     {
  45.         this.thumb       = new HorizontalSliderThumbBoth();
  46.         this.style       = TICK_BOTH;
  47.         this.min         = 1;
  48.         this.max         = 10;
  49.         this.freq        = 1;
  50.  
  51.         prevPos          =
  52.         curPos           = 0;
  53.  
  54.         width            = 200;
  55.         height           = 50;
  56.  
  57.         showBorder       = true;
  58.  
  59.         tick             = null;
  60.     }
  61.  
  62.     /**
  63.      * Sets the current slider tick mark style.
  64.      * @see #getTickStyle
  65.      * @see Slider#TICK_TOP
  66.      * @see Slider#TICK_BOTTOM
  67.      * @see Slider#TICK_BOTH
  68.      */
  69.     public void setTickStyle(int style)
  70.     {
  71.         if (this.style != style)
  72.         {
  73.             this.style = style;
  74.     
  75.             switch (style)
  76.             {
  77.                 case TICK_TOP :
  78.                     thumb = new HorizontalSliderThumbTop();
  79.                     break;
  80.     
  81.                 case TICK_BOTTOM :
  82.                     thumb = new HorizontalSliderThumbBot();
  83.                     break;
  84.     
  85.                 default :
  86.                     thumb = new HorizontalSliderThumbBoth();
  87.                     break;
  88.     
  89.             }
  90.             
  91.             invalidate();
  92.         }
  93.     }
  94.     
  95.     /**
  96.      * Returns the current slider tick mark style.
  97.      * @see #setTickStyle
  98.      * @see Slider#TICK_TOP
  99.      * @see Slider#TICK_BOTTOM
  100.      * @see Slider#TICK_BOTH
  101.      */
  102.     public int getTickStyle()
  103.     {
  104.         return style;
  105.     }
  106.     
  107.     /**
  108.      * Processes MOUSE_DOWN events.
  109.      * This is a standard Java AWT method which gets called by the AWT
  110.      * method handleEvent() in response to receiving a MOUSE_DOWN
  111.      * event. These events occur when the mouse button is pressed while
  112.      * inside this component.
  113.      * 
  114.      * @param e the event
  115.      * @param x the component-relative horizontal coordinate of the mouse
  116.      * @param y the component-relative vertical coordinate of the mouse
  117.      * 
  118.      * @return always true since the event was handled
  119.      * 
  120.      * @see java.awt.Component#mouseUp
  121.      * @see java.awt.Component#handleEvent
  122.      */
  123.     public boolean mouseDown(Event e, int x, int y)
  124.     {
  125.         moveThumb(x, true);
  126.  
  127.         return true;
  128.     }
  129.  
  130.     /**
  131.      * Processes MOUSE_DRAG events.
  132.      * This is a standard Java AWT method which gets called by the AWT
  133.      * method handleEvent() in response to receiving a MOUSE_DRAG
  134.      * event. These events occur when the mouse is moved around inside this
  135.      * component while the button is pressed.
  136.      * 
  137.      * @param e the event
  138.      * @param x the component-relative horizontal coordinate of the mouse
  139.      * @param y the component-relative vertical coordinate of the mouse
  140.      * 
  141.      * @return always true since the event was handled
  142.      * 
  143.      * @see java.awt.Component#mouseMove
  144.      * @see java.awt.Component#handleEvent
  145.      */
  146.     public boolean mouseDrag(Event e, int x, int y)
  147.     {
  148.         moveThumb(x, false);
  149.  
  150.         return true;
  151.     }
  152.  
  153.     private void do_reshape(int w, int h)
  154.     {
  155.         int hb = BORDER_X;
  156.         int vb = BORDER_Y;
  157.  
  158.         if (w < hb)
  159.             hb = w / 4;
  160.  
  161.         if (h < vb)
  162.             vb = h / 4;
  163.  
  164.         int x0 = hb;
  165.         int x1 = w - hb;
  166.         int y0 = vb;
  167.         int y1 = h - vb;
  168.  
  169.         if (x0 == 0)
  170.             x0 = 1;
  171.  
  172.         if (x1 == 0)
  173.             x1 = 1;
  174.  
  175.         if (y0 == 0)
  176.             y0 = 1;
  177.  
  178.         if (y1 == 0)
  179.             y1 = 1;
  180.  
  181.         int n = (max - min) / freq + 1;
  182.  
  183.         tick = new HorizontalSliderTick[n];
  184.  
  185.         int hs = (x1 - x0) / (n - 1), ch;
  186.  
  187.         for (int i = 0; i < n; ++i)
  188.         {
  189.             ch = i * hs;
  190.             tick[i] = new HorizontalSliderTick(x0 + ch, y0, y1, ch);
  191.         }
  192.  
  193.         thumb.resize(hs / 2, y1 - y0 - TICK_HEIGHT - 1);
  194.     }
  195.  
  196.     /**
  197.      * Moves and/or resizes this component.
  198.      * This is a standard Java AWT method which gets called to move and/or 
  199.      * resize this component. Components that are in containers with layout
  200.      * managers should not call this method, but rely on the layout manager
  201.      * instead.
  202.      * 
  203.      * @param x horizontal position in the parent's coordinate space
  204.      * @param y vertical position in the parent's coordinate space
  205.      * @param width the new width
  206.      * @param height the new height
  207.      */
  208.     public void reshape(int x, int y, int w, int h)
  209.     {
  210.         width  = w;
  211.         height = h;
  212.         
  213.         do_reshape(w, h);
  214.         
  215.         super.reshape(x, y, w, h);
  216.     }
  217.     
  218.     /**
  219.      * Paints this component using the given graphics context.
  220.      * This is a standard Java AWT method which typically gets called
  221.      * by the AWT to handle painting this component. It paints this component
  222.      * using the given graphics context. The graphics context clipping region
  223.      * is set to the bounding rectangle of this component and its <0,0>
  224.      * coordinate is this component's top-left corner.
  225.      * 
  226.      * @param g the graphics context used for painting
  227.      * @see java.awt.Component#repaint
  228.      * @see java.awt.Component#update
  229.      */
  230.     public void paint(Graphics g)
  231.     {
  232.         if (tick.length == 0)
  233.             return;
  234.         
  235.         HorizontalSliderTick t;
  236.         
  237.         g.clipRect(0, 0, width, height);
  238.         
  239.         thumb.draw(g, tick[curPos]);
  240.         
  241.         if (prevPos != curPos)
  242.             thumb.clip(g, tick[prevPos]);
  243.         
  244.         g.setColor(getBackground());
  245.         g.fillRect(0, 0, width, height);
  246.         
  247.         g.setColor(Color.black);
  248.  
  249.         int x0, x1, y, w = width - 1, h = height - 1;
  250.         boolean end;
  251.  
  252.         if (showBorder)
  253.             g.drawRect(0, 0, w, h);
  254.  
  255.         for (int i = 0; i < tick.length; ++i)
  256.         {
  257.             end = i == 0 || i == tick.length - 1;
  258.  
  259.             t = tick[i];
  260.  
  261.             if (style == TICK_TOP || style == TICK_BOTH)
  262.                 g.drawLine(t.x, t.y0 + (end ? 0 : 1), t.x, t.y0 + TICK_HEIGHT);
  263.  
  264.             if (style == TICK_BOTTOM || style == TICK_BOTH)
  265.                 g.drawLine(t.x, t.y1 - TICK_HEIGHT, t.x, t.y1 - (end ? 0 : 1));
  266.         }
  267.  
  268.         t = tick[0];
  269.  
  270.         y  = (t.y1 + t.y0) / 2;
  271.         x0 = t.x - 5;
  272.         x1 = tick[tick.length - 1].x + 5;
  273.  
  274.         g.drawLine(x0, y, x1, y);
  275.  
  276.         g.setColor(Color.gray);
  277.         g.drawLine(x1 + 1, y - 1, x0 - 1, y - 1);
  278.         g.drawLine(x0 - 1, y - 1, x0 - 1, y + 1);
  279.  
  280.         g.setColor(Color.lightGray);
  281.         g.drawLine(x0, y + 1, x1 + 1, y + 1);
  282.         g.drawLine(x1 + 1, y + 1, x1 + 1, y);
  283.  
  284.         g.setColor(Color.white);
  285.         g.drawLine(x0 - 1, y + 2, x1 + 2, y + 2);
  286.         g.drawLine(x1 + 2, y + 2, x1 + 2, y - 1);
  287.  
  288.         g.clipRect(0, 0, width, height);
  289.         
  290.         thumb.draw(g, tick[curPos]);
  291.         
  292.         prevPos = curPos;
  293.     }
  294.  
  295.     /**
  296.      * This routine updates the thumb position, paints the HorizontalSlider, and
  297.      * posts a new action event, as needed. If the thumb position has
  298.      * changed or the forcePost parameter is true the component will be painted
  299.      * and an action event posted.
  300.      * @param pos the new thumb position
  301.      * @param forcePost true forces a repaint and posting of an action message 
  302.      * even if the thumb position hasn't changed
  303.      */
  304.     protected void doMove(int pos, boolean forcePost)
  305.     {
  306.         if (tick == null)
  307.         {
  308.             prevPos = curPos = pos;
  309.             return;
  310.         }
  311.  
  312.         if (pos >= tick.length)
  313.             pos = tick.length - 1;
  314.  
  315.         if (pos != curPos || forcePost)
  316.         {
  317.             prevPos = curPos;
  318.             curPos  = pos;
  319.             paint(getGraphics());
  320.  
  321.             postEvent(new Event(this, Event.ACTION_EVENT, new Integer(curPos * freq + min)));
  322.         }
  323.     }
  324.  
  325.     private void moveThumb(int x, boolean forcePost)
  326.     {
  327.         if(tick.length > 1)
  328.         {
  329.             int dist = tick[1].x - tick[0].x;
  330.  
  331.             if (dist == 0)
  332.                 return;
  333.  
  334.             int newPos = (x - tick[0].x) / dist;
  335.  
  336.             if (newPos < 0)
  337.                 newPos = 0;
  338.  
  339.             if (((x - tick[0].x) % dist) > (dist / 2))
  340.                 ++newPos;
  341.  
  342.             doMove(newPos, forcePost);
  343.         }
  344.     }
  345.     
  346.     /**
  347.      * Ensures that this component is laid out properly, as needed.
  348.      * This is a standard Java AWT method which gets called by the AWT to 
  349.      * make sure this component and its subcomponents have a valid layout.
  350.      * If this component was made invalid with a call to invalidate(), then 
  351.      * it is laid out again.
  352.      *
  353.      * @see java.awt.Component#invalidate
  354.      */
  355.     public void validate() {
  356.         super.validate();
  357.         
  358.         do_reshape(width, height);
  359.     }
  360. }
  361.  
  362.  
  363. class HorizontalSliderTick
  364. {
  365.     int x;
  366.     int y0;
  367.     int y1;
  368.     int v;
  369.  
  370.     HorizontalSliderTick(int ix, int iy0, int iy1, int iv)
  371.     {
  372.         x  = ix;
  373.         y0 = iy0;
  374.         y1 = iy1;
  375.         v  = iv;
  376.     }
  377. }
  378.  
  379.  
  380. abstract class HorizontalSliderThumb
  381. {
  382.     protected int x;
  383.     protected int y;
  384.     protected int width;
  385.     protected int height;
  386.     protected Graphics g;
  387.     protected HorizontalSliderTick t;
  388.  
  389.     void resize(int width, int height)
  390.     {
  391.         x = (this.width = width) / 2;
  392.         y = (this.height = height) - HorizontalSlider.TICK_HEIGHT - 1 - 1;
  393.     }
  394.  
  395.     abstract void draw(Graphics g, HorizontalSliderTick t);
  396.  
  397.     protected void draw(int x0, int y0, int x1, int y1)
  398.     {
  399.         g.drawLine(t.x + x0, t.y0 + y0 + HorizontalSlider.TICK_HEIGHT + 1,
  400.                    t.x + x1, t.y0 + y1 + HorizontalSlider.TICK_HEIGHT + 1);
  401.     }
  402.  
  403.     protected void initDraw(Graphics g, HorizontalSliderTick t)
  404.     {
  405.         this.g = g;
  406.         this.t = t;
  407.  
  408.         g.setColor(Color.lightGray);
  409.         g.fillRect(t.x - x + 1, t.y0 + 2 + HorizontalSlider.TICK_HEIGHT + 1, width - 2, y - 2);
  410.  
  411.         g.setColor(Color.white);
  412.     }
  413.  
  414.     void clip(Graphics g, HorizontalSliderTick t)
  415.     {
  416.         g.clipRect(t.x - width / 2, t.y0, width + 1, height + 1);
  417.     }
  418. }
  419.  
  420.  
  421. class HorizontalSliderThumbBoth extends HorizontalSliderThumb
  422. {
  423.     void draw(Graphics g, HorizontalSliderTick t)
  424.     {
  425.         super.initDraw(g, t);
  426.  
  427.         draw(-x, y, -x, 1);
  428.         draw(-x, 1, x, 1);
  429.  
  430.         g.setColor(Color.black);
  431.         draw(-x, y, x, y);
  432.         draw(x, y, x, 1);
  433.  
  434.         g.setColor(Color.gray);
  435.         draw(1 - x, y - 1, x - 1, y - 1);
  436.         draw(x - 1, y - 1, x - 1, 2);
  437.     }
  438. }
  439.  
  440.  
  441. class HorizontalSliderThumbTop extends HorizontalSliderThumb
  442. {
  443.     void draw(Graphics g, HorizontalSliderTick t)
  444.     {
  445.         super.initDraw(g, t);
  446.  
  447.         int a = y / 5;
  448.  
  449.         draw(-x, y, -x, a);
  450.         draw(-x, a, 0, 1);
  451.  
  452.         g.setColor(Color.black);
  453.         draw(0, 1, x, a);
  454.         draw(x, a, x, y);
  455.         draw(x, y, -x, y);
  456.  
  457.         g.setColor(Color.gray);
  458.         draw(0, 2, x - 1, a);
  459.         draw(x - 1, a, x - 1, y - 1);
  460.         draw(x - 1, y - 1, 1 - x, y - 1);
  461.     }
  462. }
  463.  
  464.  
  465. class HorizontalSliderThumbBot extends HorizontalSliderThumb
  466. {
  467.     void draw(Graphics g, HorizontalSliderTick t)
  468.     {
  469.         super.initDraw(g, t);
  470.  
  471.         int a = height - HorizontalSlider.TICK_HEIGHT - 1 - 1 - y / 5;
  472.  
  473.         draw(x, 1, -x, 1);
  474.         draw(-x, 1, -x, a);
  475.         draw(-x, a, 0, y - 1);
  476.  
  477.         g.setColor(Color.black);
  478.         draw(0, y, x, a);
  479.         draw(x, a, x, 1);
  480.  
  481.         g.setColor(Color.gray);
  482.         draw(0, y - 1, x - 1, a);
  483.         draw(x - 1, a, x - 1 , 2);
  484.     }
  485. }
  486.  
  487.